/*
 * FNISVGEditor - JavaScript - based editor for SVG graphics 
 * Copyright (C) 2008 - 2009 Antti Leppä / Foyt
 * http://www.foyt.fi
 * 
 * License: 
 * 
 * Licensed under GNU Lesser General Public License Version 2.1 or later (the "LGPL") 
 * http://www.gnu.org/licenses/lgpl.html
 */
FNISVGEditorViewToolsPlugin = Class.create(FNISVGEditorPlugin, {
  initialize: function($super, editorInstance, pluginURL) {
    $super(editorInstance, pluginURL);
    
    var zoomButton = new FNIToggleableButton({});
    zoomButton.addListener('buttonUp', this, this._onZoomButtonUp);
    zoomButton.addListener('buttonDown', this, this._onZoomButtonDown);
    zoomButton.setImage(this.getPluginURL() + "/gfx/icons/22x22/tools/page-magnifier.png");
    zoomButton.setTooltip(SVGLocale.getText("viewtoolsPlugin_zoomButtonTooltip"));
    editorInstance.registerToolbarItem('zoom', zoomButton);
    
    var zoomToPageButton = new FNIPushButton({});
    zoomToPageButton.addListener('buttonClick', this, this._onZoomToPageClick);
    zoomToPageButton.setTooltip(SVGLocale.getText("viewtoolsPlugin_zoomToPageButtonTooltip"));
    zoomToPageButton.setImage(this.getPluginURL() + "/gfx/icons/22x22/actions/zoom-fit-best.png");
    editorInstance.registerToolbarItem('zoomFitPage', zoomToPageButton);
    
    this._mouseInfoPanel = new FNISVGEditorViewToolsPlugin_InfoPanel({});
    // editorInstance.getStatusBar().addGUIComponent(this._mouseInfoPanel);
    editorInstance.getViewPort().addListener("viewboxChanged", this, this._onViewBoxChanged);
	this._mouseInfoPanel.addListener("zoomChange", this, this._onInfoPanelZoomChange);
  },  
  getName: function () {
    return "viewTools";
  },
  _onZoomToPageClick: function (event) {
    this.getEditorInstance().getViewPort().zoomToPage();       
  },
  _onZoomButtonUp: function(){
    this.getEditorInstance().removeListener("mousedragstart", this);
    this.getEditorInstance().removeListener("mousedragend", this);
    this.getEditorInstance().removeListener("mousedragging", this);
    this.getEditorInstance().removeListener("mouseclick", this);
  },
  _onZoomButtonDown: function(){
    this.getEditorInstance().addListener("mousedragstart", this, this._onEditorMouseDragStart);
    this.getEditorInstance().addListener("mousedragend", this, this._onEditorMouseDragEnd);
    this.getEditorInstance().addListener("mousedragging", this, this._onEditorMouseDragging);
    this.getEditorInstance().addListener("mouseclick", this, this._onEditorMouseClick);
    this._setMode(FNISVGEditorViewToolsPlugin.MODE_ZOOMVIEW);
  },
  _onViewBoxChanged: function (event) {
    this._mouseInfoPanel.updateViewInfo(event.x1, event.y1, event.x2, event.y2, event.zoom);
  },
  _setMode: function (mode) {
  	this._mode = mode;
  },
  _onEditorMouseDragStart: function (event) {
  	switch (this._mode) {
      case FNISVGEditorViewToolsPlugin.MODE_ZOOMVIEW:
        this._moveSelectionBox(event.mouseEditorX, event.mouseEditorY, 0, 0);
        this._oldViewBox = this.getEditorInstance().getViewPort().getViewBox(); 
      break;
    }
  },
  _onEditorMouseDragEnd: function(event){
    switch (this._mode) {
      case FNISVGEditorViewToolsPlugin.MODE_ZOOMVIEW:
        var selection = this._selectionBox.getBBox();
        this.getEditorInstance().getViewPort().setViewBox(selection.x, selection.y, selection.width, selection.height);        
        this._hideSelectionBox();
        this._editorInstance.getUndoManager().addUndoableEvent(new FNISVGEditorUndoableViewPortChangeEvent(this._oldViewBox));
      break;
    }
  },
  _onEditorMouseDragging: function(event) {
    switch (this._mode) {
      case FNISVGEditorViewToolsPlugin.MODE_ZOOMVIEW:
        var width = event.mouseEditorX - event.dragStartX;
        var height = event.mouseEditorY - event.dragStartY;
        var x = event.dragStartX;
        var y = event.dragStartY;
        
        if (width < 0) {
          width = -width;
          x -= width;
        }
        
        if (height < 0) {
          height = -height;
          y -= height;
        }
        
        this._moveSelectionBox(x, y, width, height);
      break;
    }
  },
  _onEditorMouseClick: function (event) {
  	switch (this._mode) {
	    case FNISVGEditorViewToolsPlugin.MODE_ZOOMVIEW:
	      if (event.ctrlKey) 
		      this.getEditorInstance().getViewPort().zoomOut();
		    else
		      this.getEditorInstance().getViewPort().zoomIn();
		    this.getEditorInstance().getViewPort().setCenter(event.mouseEditorX, event.mouseEditorY);
	    break;
  	}
  },
  _moveSelectionBox: function (x, y, width, height) {
    if (!this._selectionBox) {
	  this._selectionBox = this.getEditorInstance().getSVGDocument().createElement("rect");
	  this._selectionBox.setAttribute('style', this.getEditorInstance().getConfigurationManager().getValue("selectionRectStyle"));
	  this.getEditorInstance().getSVGDocument().appendTemporaryElement(this._selectionBox);
	}	
		
	var controller = getSVGElementControllerVault().getElementControllerFor(this._selectionBox);
	controller.moveTo(this._selectionBox, x, y);
	controller.resizeTo(this._selectionBox, width, height);
  },
  _hideSelectionBox: function () {
  	if (!this._selectionBox) {
	  this.getEditorInstance().getSVGDocument().removeTemporaryElement(this._selectionBox);
	  this._selectionBox = null;	
	}
  }
});

FNISVGEditorViewToolsPlugin_ZoomInfo = Class.create(FNIPanel, {
  initialize: function($super, options){
	$super(options);
	
	this.domNode = new Element("div", {
	  className: 'fniSVGEditor_ViewToolsPlugin_ViewZoomInfo'
	});
	this._items = document.createElement("select");
	
	for (var i = 25; i <= 800; i = i * 2) {
	  var option = this._createOption(i);	  
	  this._items.appendChild(option);	
	}
	
	this.domNode.appendChild(this._items);
	
	this._itemsSelectChangeListener = this._onItemSelectChange.bindAsEventListener(this);
	Event.observe(this._items, "change", this._itemsSelectChangeListener);	
  },
  setValue: function (zoom) {
  	var zoomValue = Math.round(zoom * 100);
	for (var i = 0; i < this._items.options.length; i++) {
	  if (this._items.options[i].value == zoomValue) {
	  	this._items.selectedIndex = i;
		return;
	  }
	}
	
	if (!this._customOption) {
	  this._customOption = this._createOption(zoomValue);	  
	} else {
	  this._customOption.value = zoomValue;
	  this._customOption.innerHTML = zoomValue + '%';	
	  this._items.removeChild(this._customOption);	  
	}
	
	var i = this._items.options.length - 1;
	while (i > 1) {
	  var v1 = this._items.options[i].value; 
	  var v2 = this._items.options[i - 1].value;
	  
	  if ((v1 > zoomValue) && (v2 < zoomValue)) {
		this._items.insertBefore(this._customOption, this._items.options[i]);
		this._items.selectedIndex = i;	
		return;	
	  }	  
	  i--;
	}
	
	this._items.appendChild(this._customOption);
	this._items.selectedIndex = this._items.options.length - 1
  },
  _createOption: function (pct) {
  	var option = document.createElement("option");
	option.value = pct;
	option.innerHTML = pct + '%';
	return option;
  },
  _onItemSelectChange: function (event) {
  	var element = Event.element(event);
	this.fire("zoomChange", {
	  zoom: (element.value / 100)
	});
  }  	
});

FNISVGEditorViewToolsPlugin_InfoPanel = Class.create(FNIPanel, 
  /**
   * @scope FNISVGEditorViewToolsPlugin_MouseInfoPanel.prototype
   */ { 
  /**
   * Constructor 
   * 
   * @param {Object} $super superclass
   * @param {Hash} options  
   */
  initialize: function($super, options) {
    $super(options);
	
	this._mouseInfoElementX = $(document.createElement("div"));	
	this._mouseInfoElementY = $(document.createElement("div"));
	this._viewInfoElementX = $(document.createElement("div"));
    this._viewInfoElementY = $(document.createElement("div"));	
	this._mouseInfoPanel = $(document.createElement("div"));
	this._viewInfoPanel = $(document.createElement("div"));
  
	this._mouseInfoElementX.addClassName('fniSVGEditor_ViewToolsPlugin_MouseInfoX');
	this._mouseInfoElementY.addClassName('fniSVGEditor_ViewToolsPlugin_MouseInfoY');
    this._viewInfoElementX.addClassName('fniSVGEditor_ViewToolsPlugin_ViewInfoX');
    this._viewInfoElementY.addClassName('fniSVGEditor_ViewToolsPlugin_ViewInfoY');
    
	this._mouseInfoPanel.addClassName('fniSVGEditor_ViewToolsPlugin_MouseInfoPanel');
	this._viewInfoPanel.addClassName('fniSVGEditor_ViewToolsPlugin_ViewInfoPanel');
	
	this._mouseInfoPanel.appendChild(this._mouseInfoElementX);
	this._mouseInfoPanel.appendChild(this._mouseInfoElementY);    
	this._viewInfoPanel.appendChild(this._viewInfoElementX);
    this._viewInfoPanel.appendChild(this._viewInfoElementY);
	
	this.domNode.appendChild(this._mouseInfoPanel);
	this.domNode.appendChild(this._viewInfoPanel);
	
	this._zoomInfoPanel = new FNISVGEditorViewToolsPlugin_ZoomInfo();
	this._zoomInfoPanel.addListener("zoomChange", this, this._onZoomChange);
	this.addGUIComponent(this._zoomInfoPanel);
		
	this.domNode.addClassName('fniSVGEditor_ViewToolsPlugin_InfoPanel');
  },
  updateMouseInfo: function (x, y) {
  	this._mouseInfoElementX.innerHTML = Math.roundTo(x, 3).toFixed(3);
	this._mouseInfoElementY.innerHTML = Math.roundTo(y, 3).toFixed(3);
  },
  updateViewInfo: function (x1, y1, x2, y2, zoom) {
    var width = x2 - x1;
    var height = y2 - y1;
    
    this._viewInfoElementX.innerHTML = Math.roundTo(x1, 3).toFixed(3) + ' - ' + Math.roundTo(x2, 3).toFixed(3) + ' (' + Math.roundTo(width, 3).toFixed(3) + ')';
    this._viewInfoElementY.innerHTML = Math.roundTo(y1, 3).toFixed(3) + ' - ' + Math.roundTo(y2, 3).toFixed(3) + ' (' + Math.roundTo(height, 3).toFixed(3) + ')';
	  this._zoomInfoPanel.setValue(zoom);
  },
  _onZoomChange: function (event) {
  	this.fire("zoomChange", {
	  zoom: event.zoom
	});
  }
});

Object.extend(FNISVGEditorViewToolsPlugin, {
  MODE_ZOOMVIEW: 'zoomview'  	
});

document.fire("svgEditorPluginLoaded:viewTools", { pluginClass: FNISVGEditorViewToolsPlugin});
